
package com.loser.csp.dal.interceptor;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

/**
 * sql拦截
 *
 * @author jefferry.lu
 * @version $Id: BipCommonInterceptor.java, v 0.1 2013-4-1 上午10:37:34 jefferry.lu Exp $
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})})
public class MybatisSqlInterceptor implements Interceptor {

    /**
     * SQL输入日志.
     */
    private final static Logger logger = LoggerFactory.getLogger("sql-log");

    /**
     * @param o
     * @return
     */
    private String getParamByMap(Map o) {
        StringBuffer strBuffer = new StringBuffer("[");
        Set<Map.Entry> set = o.entrySet();
        for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
            Map.Entry entry = (Map.Entry) iterator.next();
            strBuffer.append(entry.getKey()).append(":");
            if (entry.getValue() instanceof String) {
                strBuffer.append(entry.getValue());
            } else {
                strBuffer.append(ToStringBuilder.reflectionToString(entry.getValue()));
            }
            strBuffer.append(" ");
        }
        return strBuffer.append("]").toString();
    }

    /**
     * @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

        BoundSql boundSql = statementHandler.getBoundSql();

        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler);

        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
        String params = "";
        Object o = boundSql.getParameterObject();
        if (o != null) {
            if (o instanceof String) {
                params = o.toString();
            } else {
                if (o instanceof Map) {
                    params = getParamByMap((Map) o);
                } else {
                    params = ToStringBuilder.reflectionToString(o);
                }
            }
        }

        if (logger.isInfoEnabled()) {
            logger.info("sql语句:{},参数params:{}", originalSql, params);
        }

        return invocation.proceed();
    }

    /**
     * @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
     */
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    /**
     * @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
     */
    @Override
    public void setProperties(Properties properties) {
    }

}
